Appearance
《C语言程序设计》第一学期重修试卷A (精选06)
一、选择题(本大题共20小题,每小题2分,共40分)
(1) 有以下定义:
int a[4][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int (*ptr)[3] = a, *p = a[0];2
则下列能够正确表示数组元素 a[1][2] 的表达式是(D)。
A. *(((*ptr+1)[2]))
B. *(*(p+5))
C. (*ptr+1)+2
D. *(*(a+1)+2)
查看答案与解析
答案:D
解析:
a是二维数组名,a+1指向第1行(即a[1])。*(a+1)是第1行首地址,即&a[1][0]。*(a+1)+2是&a[1][2]。*(*(a+1)+2)就是a[1][2]。
A 语法错误。B 中 p 是 int*,p+5 指向 a[1][2],但 *(p+5) 已经是 a[1][2],再加 * 错误。C 是指针加法,不是取值。
难度: ⭐⭐⭐
考点: #指针与数组 #二维数组
💡 学习锦囊
📖 相关公式与知识点:
- 二维数组
a[i][j]的等价表示:*(*(a+i)+j)*(a[i]+j)(*(a+i))[j]
思路分析
理解二维数组的指针表示法,注意指针的类型和层级。
🔄 举一反三
ptr是int (*)[3]类型,ptr+1移动多少字节?查看练习答案与解析
答案:12 字节(3个int) 解析:
ptr指向包含3个int的数组,所以ptr+1跳过3个int。
(2) 若 int i=10;,执行下列程序后,变量 i 的正确结果是(A)。
switch (i)
{
case 9: i += 1;
case 10: i += 1;
case 11: i += 1;
default: i += 1;
}2
3
4
5
6
7
A. 13
B. 12
C. 11
D. 10
查看答案与解析
答案:A
解析: switch 语句中,case 匹配后如果没有 break,会继续执行后面的 case(穿透)。i=10 匹配 case 10,然后依次执行 case 11 和 default,共加 3 次。i = 10 + 3 = 13。
难度: ⭐⭐
考点: #switch语句
💡 学习锦囊
📖 相关公式与知识点:
- switch 穿透:匹配后无 break 则继续执行后续 case。
- 每个 case 通常需要 break。
易错点
不要忘记 break,否则会出现意外穿透。
🔄 举一反三
- 若在每个 case 后都加上
break;,i 的最终值是多少?查看练习答案与解析
答案:11 解析:匹配 case 10 后执行
i+=1,遇到 break 跳出,i=11。
(3) 以下程序段的输出结果是(B)。
int x = 3;
do
{
printf("%3d", x -= 2);
} while (!(--x));2
3
4
5
A. 1
B. 1 -2
C. 3 0
D. 死循环
查看答案与解析
答案:B
解析:
- 第一次:x -= 2,x = 1,输出
1。然后 --x,x = 0,!0= 1(真),继续循环。 - 第二次:x -= 2,x = -2,输出
-2。然后 --x,x = -3,!(-3)=!非0= 0(假),结束循环。
输出: 1 -2
难度: ⭐⭐⭐
考点: #do-while循环 #自增自减
💡 学习锦囊
📖 相关公式与知识点:
- do-while 至少执行一次。
--x先减后用,x--先用后减。
思路分析
注意 do-while 的条件判断在循环体之后。
🔄 举一反三
- 若将
while (!(--x))改为while (!(x--)),输出是什么?查看练习答案与解析
答案:1 解析:第一次 x-=2 后 x=1,输出 1。x-- 先用后减,
!1=0,循环结束。
(4) 以下所列的各函数首部中,正确的是(C)。
A. void play(var :integer, var b:integer)
B. void play(int a,b)
C. void play(int a, int b)
D. Sub play(a as integer, b as integer)
查看答案与解析
答案:C
解析: A 是 Pascal 语法。B 缺少第二个参数的类型。C 是标准 C 语法。D 是 VB 语法。
难度: ⭐
考点: #函数定义
💡 学习锦囊
📖 相关公式与知识点:
- C 函数格式:
返回类型 函数名(参数类型 参数名, ...)。 - 每个参数都必须指定类型。
思路分析
区分不同编程语言的函数定义语法。
🔄 举一反三
int func(int a, float b)的返回值类型是什么?查看练习答案与解析
答案:int 解析:函数首部最左边的类型就是返回值类型。
(5) 以下程序的输出结果是(A)。
main()
{
int x = 023;
printf("%d\n", --x);
}2
3
4
5
A. 18
B. 22
C. 23
D. 19
查看答案与解析
答案:A
解析:023 是八进制数,等于十进制的 19(2×8 + 3 = 19)。--x 先减后用,x 先变为 18,再输出 18。
难度: ⭐⭐
考点: #八进制数 #自增自减
💡 学习锦囊
📖 相关公式与知识点:
- 以 0 开头的整数是八进制。
- 八进制 023 = 十进制 19。
--x先自减再使用,x--先使用再自减。
思路分析
注意数字前缀表示的进制,以及前缀自减与后缀自减的区别。
🔄 举一反三
int x = 0x1A; printf("%d", x);输出是多少?查看练习答案与解析
答案:26 解析:0x1A = 1×16 + 10 = 26。
(6) 下列4个函数中,能实现交换变量值的功能的是(C)。
A. void fun_a(int x, int y) { int *p; *p=x; x=y; y=*p; }
B. void fun_b(int *x, int *y) { int *p; *x=*y; *y=*x; }
C. void fun_c(int *x, int *y) { *x=*x+*y; *y=*x-*y; *x=*x-*y; }
D. void fun_d(int x, int y) { int p; p=x; x=y; y=p; }
查看答案与解析
答案:C
解析: A 中 p 未初始化就解引用,错误。B 中先执行 *x=*y,x 和 y 指向的值已经相同,再 *y=*x 无效果。C 使用加减法交换,无需临时变量,正确。D 是值传递,交换的是形参,不影响实参。
难度: ⭐⭐⭐
考点: #函数参数传递 #指针
💡 学习锦囊
📖 相关公式与知识点:
- 值传递:不改变实参。
- 地址传递:可以改变实参。
- 交换两个数的方法:临时变量、加减法、异或法。
思路分析
注意区分值传递和地址传递。
🔄 举一反三
- 用异或法交换两个整数 a 和 b 的代码是什么?
查看练习答案与解析
答案:
a = a ^ b; b = a ^ b; a = a ^ b;解析:异或法不需要临时变量,但仅适用于整数。
二、填空题(本大题共13空,每空2分,共26分)
(1) 判断 n 是否是素数,若是,则返回 1,否则返回 0。
int prim(int n)
{
int m;
for (m = 2; m <= n / 2; m++)
if (n % m == 0)
return 0;
return 1;
}2
3
4
5
6
7
8
查看答案与解析
答案: n % m == 0
解析: 素数是只能被 1 和自身整除的数。若 n 能被 m(2 到 n/2 之间)整除,则不是素数,返回 0。循环结束都没找到因子,返回 1。
难度: ⭐⭐
考点: #素数判断
💡 学习锦囊
📖 相关公式与知识点:
- 只需判断到 √n 或 n/2 即可。
- 1 不是素数。
思路分析
优化:可以只判断到 sqrt(n)。
🔄 举一反三
- 为什么循环只需到 n/2 或 sqrt(n)?
查看练习答案与解析
答案:若 n 有大于 sqrt(n) 的因子,则必有小于 sqrt(n) 的因子与之配对。 解析:如 n=100,sqrt(100)=10,若能被 20 整除,必能被 5 整除。
(2) 下述程序段是要实现在数组中查找最大元素和最小元素的下标。
#include <stdio.h>
void find(int *a, int n, int *max, int *min)
{
int i;
*max = *min = 0;
for (i = 1; i < n; i++)
if (a[i] > a[*max])
*max = i;
else if (a[i] < a[*min])
*min = i;
}
void main()
{
int a[] = {5, 8, 7, 6, 2, 7, 3};
int max, min;
find(a, 7, &max, &min);
printf("\nmax=%d, min=%d", max, min);
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
查看答案与解析
答案: *max = i; 和 *min = i;
解析: 通过指针返回最大和最小元素的下标。当找到更大的元素时,更新 *max;找到更小的元素时,更新 *min。
难度: ⭐⭐
考点: #指针参数 #查找最值
💡 学习锦囊
📖 相关公式与知识点:
- 通过指针可以在函数内修改外部变量。
思路分析
注意 else if 的使用,避免同一个元素同时更新 max 和 min。
🔄 举一反三
- 若数组所有元素相等,max 和 min 的值是多少?
查看练习答案与解析
答案:max=0, min=0 解析:初始化为 0,所有元素相等时不会触发任何更新。
(3) 下面的程序当输入为字符串 "qwert?" 时的输出结果是 rxfsu。
main()
{
char c;
while ((c = getchar()) != '?')
putchar(++c);
}2
3
4
5
6
查看答案与解析
答案: rxfsu
解析: 读取字符,遇到 '?' 停止。每个字符先自增再输出:
- q → r, w → x, e → f, r → s, t → u
输出:rxfsu
难度: ⭐⭐
考点: #字符输入输出
💡 学习锦囊
📖 相关公式与知识点:
getchar()和putchar()用于字符输入输出。++c先自增再使用。
思路分析
注意字符的 ASCII 码运算。
🔄 举一反三
- 若输入 "abc?",输出是什么?
查看练习答案与解析
答案:bcd 解析:a→b, b→c, c→d,遇到 ? 停止。
(4) 假设有如下语句:
int a;
float b, c;
scanf("%2d%3f%4f", &a, &b, &c);
printf("\na=%d, b=%f, c=%f\n", a, b, c);2
3
4
若从键盘输入:9876543210
则输出应为:a=98, b=765.000000, c=4321.000000
查看答案与解析
答案: a=98, b=765.000000, c=4321.000000
解析:
%2d取 2 位:98 → a%3f取 3 位:765 → b%4f取 4 位:4321 → c
难度: ⭐⭐
考点: #scanf格式控制
💡 学习锦囊
📖 相关公式与知识点:
- scanf 宽度限制对浮点数同样适用。
思路分析
注意 scanf 的宽度限制是按字符数而非数值大小。
🔄 举一反三
- 若输入
1234567890,a, b, c 的值分别是多少?查看练习答案与解析
答案:a=12, b=345.0, c=6789.0 解析:%2d 取 12,%3f 取 345,%4f 取 6789。
(5) 下面的函数用于实现将一个字符串按逆序存放。
void convert(char s[])
{
char m;
int i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
m = s[i];
s[i] = s[j];
s[j] = m;
}
printf("%s\n", s);
}2
3
4
5
6
7
8
9
10
11
12
查看答案与解析
答案: j = strlen(s) - 1 和 s[i] = s[j]
解析:
- j 应初始化为最后一个字符的下标:
strlen(s) - 1。 - 交换
s[i]和s[j]。
难度: ⭐⭐
考点: #字符串逆序
💡 学习锦囊
📖 相关公式与知识点:
- 字符串长度:strlen 返回字符数,下标范围 0 到 strlen-1。
- 双指针法:一个从头,一个从尾,向中间移动并交换。
思路分析
注意 j 的初始值是 strlen(s) - 1 而非 strlen(s)。
🔄 举一反三
- 若字符串 s = "hello",逆序后是什么?
查看练习答案与解析
答案:olleh 解析:h↔o, e↔l,中间字符 l 不变。
(6) 以下函数 fun 的功能是用选择排序法对数组的数据按从小到大的顺序排列。
void fun(int a[], int n)
{
int i, j, k, temp;
for (i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
if (a[j] < a[k])
k = j;
if (k != i)
{
temp = a[k];
a[k] = a[i];
a[i] = temp;
}
}
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
查看答案与解析
答案: j < n 和 k != i
解析:
- 内层循环 j 从 i+1 到 n-1,条件是
j < n。 - 若 k 不等于 i,说明找到了更小的元素,需要交换。
难度: ⭐⭐
考点: #选择排序
💡 学习锦囊
📖 相关公式与知识点:
- 选择排序:每轮找最小元素,放到已排序部分的末尾。
- 时间复杂度 O(n²)。
思路分析
理解选择排序的两层循环逻辑。
🔄 举一反三
- 选择排序和冒泡排序的主要区别是什么?
查看练习答案与解析
答案:选择排序每轮只交换一次(找最小),冒泡排序每轮可能交换多次(相邻比较)。 解析:选择排序的比较次数固定为 n(n-1)/2,交换次数最多 n-1 次。
(7) 函数 fun,其功能是求两个整数的最大公约数。
int fun(int x, int y)
{
int a, b, t, r;
a = x;
b = y;
while ((r = a % b) != 0)
{
a = b;
b = r;
}
return (b);
}2
3
4
5
6
7
8
9
10
11
12
查看答案与解析
答案: (r = a % b) != 0 和 b = r
解析: 辗转相除法(欧几里得算法):
- 计算 a % b 的余数 r
- 若 r = 0,则 b 是最大公约数
- 否则,a = b, b = r,继续循环
难度: ⭐⭐⭐
考点: #最大公约数 #辗转相除法
💡 学习锦囊
📖 相关公式与知识点:
- GCD(a, b) = GCD(b, a % b)
- 当余数为 0 时,除数就是最大公约数。
思路分析
理解辗转相除法的数学原理。
🔄 举一反三
- 用辗转相除法求 GCD(48, 18) 的过程是怎样的?
查看练习答案与解析
答案:48%18=12, 18%12=6, 12%6=0,GCD=6。 解析:每次用除数除以余数,直到余数为 0。
(8) 以下程序中,主函数调用了 LineMax 函数,实现在 N 行 M 列的二维数组中,找出每一行上的最大值。
#define N 3
#define M 4
void LineMax(int x[N][M])
{
int i, j, p;
for (i = 0; i < N; i++)
{
p = 0;
for (j = 1; j < M; j++)
if (x[i][p] < x[i][j])
p = j;
printf("The max value in line %d is %d\n", i, x[i][p]);
}
}
main()
{
int x[N][M] = {1, 5, 7, 4, 2, 6, 4, 3, 8, 2, 3, 1};
LineMax(x);
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
查看答案与解析
答案: p = j
解析: 当发现当前行第 j 列的元素大于第 p 列的元素时,更新 p 为 j。p 始终指向当前行的最大值位置。
难度: ⭐⭐
考点: #二维数组 #查找最值
💡 学习锦囊
📖 相关公式与知识点:
- 遍历每行,记录最大值的下标。
思路分析
注意 p 记录的是列下标,不是值。
🔄 举一反三
- 如何同时记录最大值及其下标?
查看练习答案与解析
答案:用两个变量,一个存最大值
max_val,一个存下标max_idx。 解析:if (x[i][j] > max_val) { max_val = x[i][j]; max_idx = j; }
三、判断题(本大题共10小题,每小题2分,共20分)
(1) C语言允许在复合语句内定义自动变量。(√)
查看答案与解析
答案:√
解析: C 语言支持块作用域,在复合语句(花括号内)可以定义变量,该变量只在块内有效。
难度: ⭐
考点: #变量作用域
💡 学习锦囊
📖 相关公式与知识点:
- 块作用域:在
{}内定义的变量,作用域仅限于该块。 - 自动变量默认就是 auto 存储类别。
思路分析
复合语句可以包含声明和语句两部分。
🔄 举一反三
- 在复合语句内定义的变量,离开复合语句后还能访问吗?
查看练习答案与解析
答案:不能 解析:变量生命周期随块结束而终止。
(2) 全局变量可以和局部变量重名,且全局变量优先。(×)
查看答案与解析
答案:×
解析: 全局变量和局部变量可以重名,但局部变量优先(屏蔽全局变量)。在局部变量的作用域内,访问的是局部变量而非全局变量。
难度: ⭐
考点: #变量作用域
💡 学习锦囊
📖 相关公式与知识点:
- 同名变量:局部优先原则,局部变量会屏蔽同名的全局变量。
- 使用
::(C++)或避免重名来解决。
思路分析
就近原则:编译器优先使用最近作用域内的变量。
🔄 举一反三
- 如何在局部作用域内访问被屏蔽的全局变量?
查看练习答案与解析
答案:C 语言中无法直接访问(C++ 可用
::变量名)。 解析:最佳实践是避免全局和局部变量重名。
(3) 若一个函数的返回类型为 void,则表示其没有返回值。(√)
查看答案与解析
答案:√
解析: void 表示无返回值,函数体内不需要 return 语句,或只能写 return;。
难度: ⭐
考点: #函数返回值
💡 学习锦囊
📖 相关公式与知识点:
- void 函数可以写
return;(不带值)来提前退出。 - void 函数不能返回值,否则编译错误。
思路分析
void = 空 = 无返回值。
🔄 举一反三
- void 函数中写
return 0;会怎样?查看练习答案与解析
答案:编译错误 解析:void 函数不能返回任何值。
(4) 在程序运行过程中,系统分配给实参和形参的内存单元是相同的。(×)
查看答案与解析
答案:×
解析: 实参和形参是不同的内存单元。函数调用时,实参的值被复制到形参中(值传递),它们占用不同的内存空间。
难度: ⭐
考点: #参数传递
💡 学习锦囊
📖 相关公式与知识点:
- 值传递:形参是实参的副本,修改形参不影响实参。
- 地址传递:传递指针时,形参和实参指向同一地址。
思路分析
实参和形参各自独立分配内存。
🔄 举一反三
- 若实参是数组名,形参和实参的内存关系是什么?
查看练习答案与解析
答案:形参得到的是数组首地址的副本,但指向同一数组。 解析:数组名退化为指针传递,形参和实参指向同一块内存。
(5) 对于 continue 和 break 这两条语句,只有 break 可用来实现循环体的中止。(×)
查看答案与解析
答案:×
解析: break 用于跳出整个循环,continue 用于跳过当前迭代继续下一次循环。两者都可以改变循环的执行流程。
难度: ⭐
考点: #break #continue
💡 学习锦囊
📖 相关公式与知识点:
- break:终止整个循环。
- continue:跳过本次循环剩余部分,进入下一次迭代。
- 两者都不是"中止"循环的唯一方式。
思路分析
注意"中止"一词的歧义:break 是终止,continue 是跳过。
🔄 举一反三
- 在嵌套循环中,break 跳出几层循环?
查看练习答案与解析
答案:只跳出最内层的一层循环。 解析:break 只影响直接包含它的那层循环。
(6) 已知:char c='A'; int i=1, j; 执行语句 j = !c && i++; 则 i 和 j 的值分别是 0,1。(×)
查看答案与解析
答案:×
解析:!c = !'A' = !非0 = 0。由于 && 短路求值,左边为 0,右边 i++ 不会执行。所以 i = 1,j = 0。题目说 i=0, j=1 是错误的。
难度: ⭐⭐
考点: #逻辑运算 #短路求值
💡 学习锦囊
📖 相关公式与知识点:
- 短路求值:
&&左假则停,||左真则停。 !非0= 0,!0= 1。
思路分析
先计算 !c,再判断是否短路。
🔄 举一反三
- 若
c='\0'(ASCII 为 0),执行后 i 和 j 的值是多少?查看练习答案与解析
答案:i=2, j=1 解析:
!0=1,不短路,i++执行,i=2,1&&1=1,j=1。
(7) 所有定义在主函数之前的函数无需进行声明。(×)
查看答案与解析
答案:×
解析: 如果函数定义在使用之前,确实不需要额外声明。但如果函数定义在使用之后,或者跨文件调用,则需要声明。题目说"所有"太绝对。
难度: ⭐
考点: #函数声明
💡 学习锦囊
📖 相关公式与知识点:
- 函数定义在调用之前:无需声明。
- 函数定义在调用之后:需要前置声明(函数原型)。
- 跨文件调用:需要头文件中的声明。
思路分析
关键看定义和调用的先后顺序。
🔄 举一反三
- 函数原型(声明)的格式是什么?
查看练习答案与解析
答案:
返回类型 函数名(参数类型列表);如int max(int a, int b);解析:函数原型以分号结尾,不需要函数体。
(8) & 既可以用作单目运算符也可以用作双目运算符。(√)
查看答案与解析
答案:√
解析:& 作为单目运算符是取地址(如 &a),作为双目运算符是按位与(如 a & b)。
难度: ⭐
考点: #运算符
💡 学习锦囊
📖 相关公式与知识点:
- 单目
&:取地址运算符,优先级很高。 - 双目
&:按位与运算符,优先级较低。 - 类似地,
*也是单目(解引用)和双目(乘法)两用。
思路分析
根据操作数个数区分运算符的含义。
🔄 举一反三
*作为单目和双目运算符分别是什么含义?查看练习答案与解析
答案:单目
*是解引用(取内容),双目*是乘法。 解析:*p取 p 指向的值,a * b是乘法。
(9) 宏定义和文件包含都是 C 语言中的编译预处理命令,对它们的处理是在编译前完成的。(√)
查看答案与解析
答案:√
解析: 预处理命令(以 # 开头)在编译之前由预处理器处理,包括宏定义、文件包含、条件编译等。
难度: ⭐
考点: #预处理
💡 学习锦囊
📖 相关公式与知识点:
- 预处理阶段:处理
#define、#include、#ifdef等指令。 - 预处理完成后才进行编译、汇编、链接。
思路分析
记住 C 程序的编译流程:预处理 → 编译 → 汇编 → 链接。
🔄 举一反三
#include <stdio.h>和#include "stdio.h"有什么区别?查看练习答案与解析
答案:
<>从系统目录搜索,""先从当前目录搜索再搜系统目录。 解析:自定义头文件通常用"",标准库头文件用<>。
(10) 一个函数利用 return 不可能同时返回多个值。(√)
查看答案与解析
答案:√
解析: return 只能返回一个值。如果需要返回多个值,可以通过指针参数、结构体或全局变量实现。
难度: ⭐
考点: #函数返回值
💡 学习锦囊
📖 相关公式与知识点:
- return 只能返回一个值。
- 多值返回方案:指针参数、结构体、全局变量。
思路分析
return 语句的本质是将一个值放入约定的寄存器或栈位置。
🔄 举一反三
- 如何用结构体返回多个值?
查看练习答案与解析
答案:定义结构体类型,函数返回该结构体。 解析:如
struct Result { int max; int min; }; struct Result find(int a[], int n);
四、编程题(本大题共1小题,共14分)
编程打印如下的杨辉三角形,具体要求如下:
(1) 从主函数中输入欲打印的杨辉三角形行数; (2) 用子函数实现杨辉三角形的显示。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 12
3
4
5
查看答案与解析
参考答案:
#include <stdio.h>
void printYangHui(int n)
{
int a[20][20] = {0};
int i, j;
for (i = 0; i < n; i++)
{
a[i][0] = 1; /* 每行第一个元素为1 */
a[i][i] = 1; /* 每行最后一个元素为1 */
}
/* 计算中间元素 */
for (i = 2; i < n; i++)
for (j = 1; j < i; j++)
a[i][j] = a[i-1][j-1] + a[i-1][j];
/* 输出 */
for (i = 0; i < n; i++)
{
/* 打印前导空格 */
for (j = 0; j < n - 1 - i; j++)
printf(" ");
for (j = 0; j <= i; j++)
printf("%4d", a[i][j]);
printf("\n");
}
}
main()
{
int n;
printf("请输入行数: ");
scanf("%d", &n);
printYangHui(n);
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
解析: 杨辉三角形的特点:
- 每行第一个和最后一个元素为 1
- 中间元素等于上一行左上方和正上方元素之和
- 第 i 行有 i+1 个元素
难度: ⭐⭐⭐
考点: #杨辉三角形 #二维数组 #函数
💡 学习锦囊
📖 相关公式与知识点:
- 杨辉三角形:C(n, k) = C(n-1, k-1) + C(n-1, k)
- 可以用一维数组优化空间复杂度。
思路分析
先初始化边界,再用递推公式计算中间元素。
易错点
- 数组下标不要越界。
- 注意每行元素个数等于行号+1。
🔄 举一反三
- 如何用一维数组实现杨辉三角形?
查看练习答案与解析
答案:
cvoid printYangHui(int n) { int a[20] = {1}; int i, j; for (i = 0; i < n; i++) { for (j = i; j > 0; j--) a[j] = a[j] + a[j-1]; for (j = 0; j <= i; j++) printf("%4d", a[j]); printf("\n"); } }1
2
3
4
5
6
7
8
9
10
11
12
13解析:从后向前更新,避免覆盖。